More results...

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
post
page
Python IDE Dashboard

Build Your Own Pizza – Price Calculator

Welcome to this beginner-friendly Python challenge! In this task, you will create a simple pizza ordering system that calculates the total cost based on a customer’s choices. This is a great way to practise input handling, selection (if statements), and basic arithmetic in Python.

The Challenge

For this challenge, you will create a program that allows a customer to build their own pizza by choosing:

  • Pizza size (Small, Medium, Large)
  • Base type (Classic crust, thin crust or deep pan)
  • Number of toppings
  • Eat in or takeaway

Your program will then calculate and display the total price.

Finally, the user will be able to enter a discount code. If this discount code is correct they will receive a 20% discount on the price of their pizza!

To complete this challenge, you willl need to use:

  • input() statements to collect user choices
  • if / elif / else statements
  • Variables to store prices
  • Basic maths operations

Pizza Options & Costs

The following poster informs the customer of the process of making their own pizza and explains how the cost is calculated.

Python Code

We have started the code for you. Your job is to complete this code to let the user enter all their desired options for their pizza and to adjust the price of the pizza accordingly.

Extension Task: Discount Code

After entering all their options the customer should be given the opportunity to enter a discount code if they want to. If the user enter the code “P1ZZ4”, they should benefit from a 20% discount on the total price of their pizza!

Test Plan

Once your code is complete, test it using the following test plan to make sure all your calculations are correct!

Test # Input Values Expected Output Pass / Fail
#1 Pizza Size: Small (S)
Base: Deep
Number of Toppings 3
Eat in? Yes
Discount Code: N/A
Pizza Price: £14.50
#2 Pizza Size: Large (L)
Base: Thin
Number of Toppings 4
Eat in? No
Discount Code: FREEPIZZA
Pizza Price: £17.00
#3 Pizza Size: Medium (M)
Base: Classic
Number of Toppings 5
Eat in? Yes
Discount Code: P1ZZ4
Pizza Price: £14.00
unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Estimating Pi Using Coprime Numbers

Did you know you can estimate the value of π (pi) using probability and number theory?

This challenge explores a surprising mathematical relationship:
The probability that two randomly chosen integers are coprime, P(\text{coprime}) is equal to \frac{6}{\pi^2}

Coprime numbers?

Two numbers are coprime if their only common factor is 1.

Using this idea, you can estimate π by randomly generating pairs of integers and checking how often they are coprime.

If:
P(\text{coprime}) = \frac{6}{\pi^2}
Then we can rearrange to estimate π:
\pi \approx \sqrt{\frac{6}{P(\text{coprime})}}

So the aim of this challenge will be to write a program to:

  • Generate many random pairs of integers
  • Count how many of these pairs are coprime
  • Use the ratio to estimate π

Not that to work out if two numbers are coprime, we will need to create a function to calculate their Greatest Common Denominator.

Step 1: Generating N pairs of random integers

For this step we will use the random library to generate random integer values (between 1 and 10,000), and a for loop, to generate N pairs.

import random, math

N = 1000
for i in range(0,N):
   number1 = random.randint(1,10000)
   number2 = random.randint(1,10000)

Step 2: Finding out if our pair of numbers are coprime

To check if two numbers are coprime, we first need to calculate their Greatest Common Denominator. We can do so using the following function, based on Euclid’s Division Algorithm:

def gcd(a, b):
    # Repeat until b becomes 0
    while b != 0:
        remainder = a % b   # Find the remainder when a is divided by b
        a = b               # Move b into a
        b = remainder       # Move remainder into b

    # When b is 0, a contains the GCD
    return a

We can use this function in our previous for loop to count how many pairs of numbers are coprime:

import random, math

N = 1000
coprime_count = 0

for i in range(0,N):
   number1 = random.randint(1,10000)
   number2 = random.randint(1,10000)
   if gcd(number1, number2) == 1:
      coprime_count = coprime_count + 1

Step 3: Outputting the ratio of coprime pairs:

We can now calculate and display the ratio of coprime pairs (Probability that two randomly generated numbers are coprime):

P(coprime) = \frac{coprime\_count}{N}
probability = coprime_count / N

Estimating Pi

We can now estimate Pi using the following formula:
\pi \approx \sqrt{\frac{6}{P(\text{coprime})}}

pi_estimate = math.sqrt(6 / probability)

And finally we can display our estimate on screen as well as calculate the percentage of accuracy of our estimate:

print("Number of pairs", N)
print("Number of coprime", coprime_count)
print("Estimated value of Pi:", pi_estimate)
print("Actual value of Pi:", math.pi)
print("Percentage of accuracy:", 100 - 100 * abs(math.pi - pi_estimate)/math.pi)

Python Code

Your turn! You can now complete the code below:

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Pygame Animations using a Spritesheet

In this tutorial, we will learn how to animate a character in Python using the Pygame library and a spritesheet. Instead of loading lots of separate images to animate our main sprite/character, we will use one single image containing multiple frames — a much more efficient and professional approach used in real games!

Our learning objectives are as follows:

  • Understand what a spritesheet is
  • Load and display images in Pygame
  • Extract frames from a spritesheet
  • Animate a walking character

What’s a Spritesheet?

A spritesheet is a single image that contains multiple frames to be used to create a frame-based animation.

For example: a walking character might have 6 frames showing different leg and arm positions.

Instead of loading 6 separate images, we:

  • Load one image (called a spritesheet)
  • “Cut” it into smaller pieces (frames)
  • Display these frames in sequence

Here is a spritesheet to create an animated walking ninja girl. Our animation will contain 9 frames:

When we animated these frames in sequence we will get the following animation:

Let’s now investigate the Python code to complete this animation with a 2D game implemented using the Pygame library.

Python Tutorial

Step 1: Setup the game (using Pygame)

You will need to make sure that the Pygame library is already installed on your computer.

The you will create your main python file and use the following code to initialise your game:

import pygame
import sys

pygame.init()

# Create game window
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Spritesheet Animation")

Step 2: Loading the Spritesheet

You will need to download the spritesheet below and save it in the same folder as where your Python file is saved.

Now add the following line of code to load the spritesheet file:

spritesheet = pygame.image.load("character_spritesheet.png").convert_alpha()

Step 3: Extracting Frames from the Spritesheet

We will use the following function to extract the different frames from the spritesheet: (Add this function at the top of your code)

def load_frames(sheet, x, y, frame_width, frame_height, num_frames):
    frames = []

    for i in range(num_frames):
        frame = sheet.subsurface(
            pygame.Rect(x + i * frame_width, y, frame_width, frame_height)
        )
        frames.append(frame)

    return frames

After loading the spritesheet, we will call our function. For instance to extract the top row of frames (running animation) we will start extraxcting 9 frames from position x=0 and y=0, each frame being 120 pixels wide and 160 pixels high.

Here the code we will use to extract these 9 frames:

frames = load_frames(spritesheet, 0, 0, 120, 160, 9)

We will also use two animation variables as follows:

current_frame = 0
animation_speed = 0.15

Step 4: Animating our character

Now let’s add some code to the main program loop of our game:

clock = pygame.time.Clock()
carryOn = True
while carryOn:
   screen.fill((30, 30, 30))

   # Handle events
   for event in pygame.event.get():
      if event.type == pygame.QUIT:
         running = False

   # Update animation
   current_frame += animation_speed
   if current_frame >= len(frames):
      current_frame = 0

   # Draw current frame
   screen.blit(frames[int(current_frame)], (100, 300))

   pygame.display.flip()
   clock.tick(60)

pygame.quit()
sys.exit()

Your Turn

Use the above code and spritesheet to reproduce the animation of the ninja-girl running.

The tweak the code provided to make a jumping ninja girl animation.

Finally, create one more animation of the ninja girl attacking!

Using Object Oriented Programming

Within a Pygame project, it is very likely that you will define a separate class for the main character of your game. So let’s rework the code provided above to create a NinjaGirl class. We will then respond to keyboards input to change the state of our player (e.g. from idle to running or attacking). We will also use some code to flip our character so that we can have them looking/running right or left.

When trying the code provided below use the following keyboard inputs:

  • Right arrow to run towards the right
  • Left arrow to run towards the left
  • Space bar to attack
main.pyninja_girl.py

Python Code: Main.py file

# Ninja Girl Animation using Pygame - www.101computing.net/pygame-animations-using-a-spritesheet/

import pygame
import sys
from ninja_girl import NinjaGirl

IDLE = 0
RUN = 1
JUMP = 2
ATTACK = 3
DEAD = 4

pygame.init()

# Create game window
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Spritesheet Animation")

# Create sprite
player = NinjaGirl(100, 300)
all_sprites = pygame.sprite.Group(player)

clock = pygame.time.Clock()

running = True

while running:
   screen.fill((30, 30, 30))

   # Events
   for event in pygame.event.get():
      if event.type == pygame.QUIT:
         running = False

   keys = pygame.key.get_pressed()

    # State logic
   if keys[pygame.K_RIGHT]:
       player.set_state(RUN)
       player.rect.x += 3
       player.facing_right = True

   elif keys[pygame.K_LEFT]:
       player.set_state(RUN)
       player.rect.x -= 3
       player.facing_right = False
   elif keys[pygame.K_SPACE]:
       player.set_state(ATTACK)
   else:
       player.set_state(IDLE)


   # Update + draw
   all_sprites.update()
   all_sprites.draw(screen)

   pygame.display.flip()
   clock.tick(60)

pygame.quit()
sys.exit()

Python Code: ninja_girl.py file

import pygame

IDLE = 0
RUN = 1
JUMP = 2
ATTACK = 3
DEAD = 4

class NinjaGirl(pygame.sprite.Sprite):
   #This class represents a ball. It derives from the "Sprite" class in Pygame.

   def __init__(self, x, y):
      super().__init__()

      # State
      self.state = IDLE
      self.facing_right = True

      # Animation
      self.animations = {}
      self.current_frame = 0
      self.animation_speed = 0.15

      # Load spritesheets
      self.load_animations()

      # Starting image
      self.image = self.animations[self.state][0]
      self.rect = self.image.get_rect()

      # Position
      self.rect.x = x
      self.rect.y = y


   def load_frames(self, filename, x, y, frame_width, frame_height, num_frames):
      sheet = pygame.image.load(filename).convert_alpha()
      frames = []

      for i in range(num_frames):
         frame = sheet.subsurface(
            pygame.Rect(x + i * frame_width, y, frame_width, frame_height)
         )
         frames.append(frame)

      return frames


   def load_animations(self):
      self.animations[IDLE] = self.load_frames("spritesheet-ninja-girl.png", 960, 350, 120, 160, 1)
      self.animations[RUN] = self.load_frames("spritesheet-ninja-girl.png", 0, 0, 120, 160, 9)
      self.animations[JUMP]  = self.load_frames("spritesheet-ninja-girl.png", 0, 160, 120, 160, 9)
      self.animations[ATTACK]  = self.load_frames("spritesheet-ninja-girl.png", 0, 350, 200, 160, 4)
      self.animations[DEAD] = self.load_frames("spritesheet-ninja-girl.png", 800, 350, 200, 160, 1)


   def update(self):
      frames = self.animations[self.state]

      self.current_frame += self.animation_speed
      if self.current_frame >= len(frames):
         self.current_frame = 0

      frame = frames[int(self.current_frame)]

      # Flip image if facing left
      if not self.facing_right:
         frame = pygame.transform.flip(frame, True, False)

      self.image = frame


   def set_state(self, new_state):
      if self.state != new_state:
         self.state = new_state
         self.current_frame = 0  # Reset animation



unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Tagged with:

Extracurricular Activity Selector

A high school teacher needs your help! They have been asked to organise a full set of registers for students to take part in some extracurricular activities organised by the school.

There are 100 students in the year group, and each student has selected three preferred activities. Your task is to write a Python program that:

  • Allocates each student to an activity
  • Prioritises their 1st choice, then 2nd, then 3rd
  • Ensures no activity exceeds its maximum capacity
  • Identifies any students who could not be allocated

Available Activities

There are 10 activities available:

  • Rounders
  • Football
  • Basketball
  • Dance
  • Athletics
  • Chess Club
  • Coding Club
  • Arts & Crafts
  • Tennis
  • Badminton

Each activity has a maximum capacity of 10 students.

The Data

Student choices are stored in a CSV file called choices.csv like this:

FirstName,LastName,Choice1,Choice2,Choice3,
James,Bond,Basketball,Athletics,Coding Club,
Lara,Croft,Football,Dance,Athletics,
...

The complete file is provided in the Python IDE provided below.

Python Challenge

Your task is to write a Python program that will :

    Reads the CSV file
    Loops through each student
    Allocates them:

      First choice if available
      Otherwise second choice
      Otherwise third choice

    Keeps track of:

      Students assigned to each activity
      Students who could not be assigned

Example Output

This is what the output of your code would look like:

=== Activity Allocations ===

Football (10 students)
- Lara Croft
- John Smith
...

Basketball (10 students)
- James Bond
...

=== Unallocated Students ===
- Alex Turner
- Sarah Connor

Hints

Check the following hints to help you plan your solution!

  • Use a dictionary to store activities and their current student lists
  • Use the csv module to read the file
  • Think carefully about how to check if an activity is full
  • You may want a separate list for unallocated students

Python Code

We have started the code to help you read and extract the data from the CSV file. Your task is now to complete this code to allocate each students to an activity based on their preferences when possible.

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

The Goldbach Conjecture (Python Challenge)

The Goldbach Conjecture is an unproven mathematical rule, proposed by Christian Goldbach in 1742, stating that every even integer greater than 2 is the sum of two prime numbers. Despite verification by computers up to 4 x 1018, no formal proof exists, making it one of the oldest unsolved problems in number theory!

Every even number greater than 2 can be expressed as the sum of two prime numbers.

Let’s look at some examples:

  • 10 = 3 + 7
  • 28 = 5 + 23
  • 50 = 3 + 47

Our challenge is to write a Python program that tests this conjecture for any even number provided by the end-user of this program. Our program will need to:

    Ask the user to enter an even number greater than 2
    Find two prime numbers that add up to this number
    Display the result

Example Output

Enter an even number: 28
28 = 5 + 23

Prime Numbers?

A prime number is a whole number greater than 1 that cannot be exactly divided by any whole number other than itself and 1.

The first 20 prime numbers are: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, and 71.

To help test the Goldbach Conjecture, we will use a function isPrime() that takes a whole positive number as a parameter and returns whether or not this number is a prime number. Here is the code for this function:

def isPrime(n):
   if n < 2:
      return False
   for i in range(2, int(n**0.5) + 1):
      if n % i == 0:
         return False
   return True

You can test this function using the following code:

number = int(input("Enter a whole number"))
if isPrime(number):
   print("This number is a prime number!")
else:
   print("This number is a not a prime number!")

Testing the Goldbach Conjecture

We are now going to implement an algorithm to test the Goldbach Conjecture for any given number. We will base our Python code on the following flowchart:

Python Code

Use the following IDE to complete the code for testing the Goldbach conjecture based on the above flowchart:

Extension Task

Tweak your code to use an iterative approach to check all even numbers from 4 up to 1000 and display their prime pairs.

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Estimating Pi using the Basel Problem

The Basel Problem

In the 17th century, mathematicians became fascinated by an infinite series known as the Basel Problem.
The question was simple to state but extremely difficult to solve:

What is the exact value of the following infinite series?

1/1² + 1/2² + 1/3² + 1/4² + ...

This can also be written using sigma notation:
\sum_{n=1}^{\infty}(1 / n²)

Many famous mathematicians attempted to solve it, including members of the Bernoulli family who lived in the Swiss city of Basel (hence the name of the problem). However, no one could determine its exact value.

That changed in 1734, when the brilliant mathematician Leonhard Euler discovered something remarkable.

Euler’s Remarkable Discovery

Euler proved that the infinite series actually equals:

\sum_{n=1}^{\infty}(1 / n²) = π² / 6

This result surprised mathematicians because it revealed a deep connection between:

  • Number theory (the sum of reciprocals of squares)
  • Geometry through the constant π

Rearranging Euler’s formula allows us to express π in terms of the series:

π = \sqrt{(6 × \sum_{n=1}^{\infty}(1 / n²))}

This means we can estimate π by computing a partial sum of the series.
The more terms we include, the closer we get to the true value of π.

Approximating π Numerically

Since we cannot compute an infinite number of terms, we approximate the series using the first N values:

π ≈ \sqrt{(6 × \sum_{n=1}^{N}(1 / n²))}

As N increases, the approximation becomes more accurate.
This is a perfect opportunity to use Python and an iterative algorithm to calculate an approximate value of Pi using a large number of iterations (N).

Python Challenge

Your challenge is to write a Python program that estimates the value of π using Euler’s solution to the Basel Problem.

Your program should:

    Ask the user how many terms of the series should be calculated.
    Use a loop to calculate the sum of 1 / n².
    Use Euler’s formula to estimate π.
    Display the estimated value of π.
    Display the percentage of accuracy of your estimate compared to Python’s math.pi.

Example Output:

How many terms should be used? 10000

Estimated value of Pi: 3.14149
Actual value of Pi: 3.141592653589793
Difference: 0.00010

You can now complete the code using the following Python IDE:

Improving the Accuracy

The accuracy depends on the number of terms used.

Terms (N) Approximation of π
10 3.04936
100 3.13208
1,000 3.14064
10,000 3.14149

The true value of π is approximately 3.14159265359, so the estimate improves steadily as N increases.
However, this method converges relatively slowly compared to modern algorithms such as the Gregory-Leibniz series or the Nilakantha series.

Find out more Python challenges based on estimating π using your Python skills:

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Python Challenge: How Secure Is My Password?

Passwords are the first line of defence protecting our online accounts. But how secure is your password really?

In this Python challenge we will create a program that estimates how long it would take for a hacker to guess a password using a brute-force attack.

A brute-force attack works by trying every possible password combination until the correct one is found.

Password Estimated Time to Crack
abc A few milliseconds
password Less than a second
werDFG67g$%^K1e Several years

Check our online password checker tool to estimate how secure your password is, and to estimate how long it would take for for a hacker to crack your password using a brute force attack.

Step 1 – Understanding Password Strength

The difficulty of cracking a password depends on two main factors.

1. Password Length

Longer passwords take much longer to guess.

2. Character Variety

Passwords become stronger if they include:

  • Lowercase letters (a–z)
  • Uppercase letters (A–Z)
  • Numbers (0–9)
  • Symbols (!@#$%^&*)

The more character types used, the larger the number of possible combinations.

Character Type Possible Characters
Lowercase letters 26
Uppercase letters 26
Numbers 10
Symbols ~32

Step 2 – Calculating Possible Passwords

If a password uses N possible characters and has a length of L, the total number of combinations is:

Example:

For a password that only contains 3 lowercase letters of the alphabet:

26³ = 17,576 combinations

Step 3 – Estimating Guessing Speed

Modern brute-force tools can test billions of guesses per second.

For this project we will assume:

1,000,000,000 guesses per second

The time to crack the password is therefore:

Step 4 – Python Program

To create our own “password Security Estimator” we will start by asking the user to enter a password.

password = input("Enter a password: ")

We will then work out the number of possible characters used in this password by evaluating if this password contains lowercase characters, uppercase characters, number digits and punctuation signs.

N = 0

#Let's find out if this password contains lowercase characters
for character in password:
   if character in "abcdefghijklmnopqrstuvwxyz":
      N = N + 26
      break

Now we can repeat this approach to see if the password includes uppercase characters, number digits or punctuation signs:

#Let's find out if this password contains uppercase characters
for character in password:
   if character in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
      N = N + 26
      break

#Let's find out if this password contains number digits
for character in password:
   if character in "0123456789":
      N = N + 10
      break

#Let's find out if this password contains punctuation signs
for character in password:
   if character in "!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~":
      N = N + 32
      break

We can now word out the length of the password:

L = len(password)

We can apply the formula to calculate the total number of possible combinations using the ** operator (to the power of).

combinations = N ** L

The next step is to estimate, how long, in seconds, it would take to a brute force through all these combinations based on an estimate of 1 billion guesses per seconds.

guessesPerSecond = 1000000000
seconds = combinations / guessesPerSecond

Finally we will output the results using the most appropriate unit of time (milliseconds, seconds, minutes, hours, days, months or years). To do so we will create a function to format/convert the number of seconds to the most appropriate unit of time.

def formatTime(seconds):

    if seconds < 0.001:
        return "a few milliseconds"

    if seconds < 60:
        return str(int(seconds)) + " seconds"

    minutes = seconds / 60
    if minutes < 60:
        return str(int(minutes)) + " minutes"

    hours = minutes / 60
    if hours < 24:
        return str(int(hours)) + " hours"

    days = hours / 24
    if days < 365:
        return str(int(days)) + " days"

    months = days / 30
    if months<12:
        return str(int(months)) + " months"

    years = days / 365
    return str(int(years)) + " years"

print("Estimated cracking time: " + formatTime(seconds))

Example Output

Example 1

Enter a password: abc
Estimated cracking time: a few milliseconds
Example 2

Enter a password: password
Estimated cracking time: 0.02 seconds
Example 3

Enter a password: pa$$word!
Estimated cracking time: 85 days

Your Turn

Type the code provided below in the following online IDE and estimate the time it would take to crack the following passwords:

Password Estimated Time?
qwertyuiop
P4$$w0rd
weakpassword
123456789
werDFG67g$%^K1e!

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Sports Adviser Program (Python Challenge)

Choosing a sport can be tricky! Some people enjoy team sports, others prefer individual sports. Some love being outdoors, while others prefer indoor activities.

In this Python challenge, you will create a simple sports adviser program that asks the user a series of questions and then recommends a sport based on their answers.

This challenge is perfect for practising:

  • input() statements
  • if / elif / else conditions
  • Boolean logic
  • Simple decision trees

Challenge Objective

Write a Python program that asks the user a few questions about their preferences and then suggests a sport they might enjoy.

Your program should ask questions such as:

  • Do you like team sports?
  • Do you prefer indoor or outdoor sports?
  • Do you enjoy water activities?
  • Do you like fast-paced sports?
  • Do you enjoy contact sports?

Based on the answers, your program will recommend either one or a selection of relevant sports.

Here is a selection of indoor and outdoor sports for you to consider:

Sport Team / Individual Indoor / Outdoor Contact / Non-Contact Fast Paced? Water Based?
Football Team Outdoor Contact Yes No
Basketball Team Indoor Contact Yes No
Rugby Team Outdoor Contact Yes No
Cricket Team Outdoor Non-Contact No No
Swimming Individual Indoor / Outdoor Non-Contact Yes Yes
Surfing Individual Outdoor Non-Contact Yes Yes
Running Individual Outdoor Non-Contact Yes No
Tennis Individual Indoor / Outdoor Non-Contact Yes No
Badminton Individual Indoor Non-Contact Yes No
Golf Individual Outdoor Non-Contact No No
Cycling Individual Outdoor Non-Contact Yes No
Kayaking Individual Outdoor Non-Contact Yes Yes
Volleyball Team Indoor / Outdoor Non-Contact Yes No
Squash Individual Indoor Non-Contact Yes No
Gymnastics Individual Indoor Non-Contact No No
Boxing Individual Indoor Contact Yes No
Karate Individual Indoor Contact Yes No
Rowing Team / Individual Outdoor Non-Contact Yes Yes
Table Tennis Individual Indoor Non-Contact Yes No
Field Hockey Team Outdoor Contact Yes No

Python Code

We have started the code for you, though you will need to complete this code to asks more questions about the user preferences and make more suggestions based on their preferences and on the above list of sports.

Duplicate Detection Algorithms & Big O Notation

One of the most powerful ways to understand Big O Notation is to compare two different ways of solving the same problem.

Duplicate Detection Challenge?

The aim of a duplicate detection algorithm is to determine whether a list of values contains any duplicates.
This sounds simple. But the way we solve it makes a huge difference to performance, especially when the given list contains a large number (n) of values.

The Problem

Imagine we have a list of student ID numbers:

list = [1023, 1087, 1045, 1067, 1036, 1099, 1043, 1022, 1063, 1045, 1039]

In this list of IDs we have one duplicate value: 1045 appears twice.

So let’s investigate an algorithm to detect whether a list contains duplicate values. We will compare two approaches:

  1. A solution using nested for loops (Brute force approach)
  2. A more efficient solution using a set (Hash Table)

Method 1: Using Nested Loops (Brute Force)

With this approach we will compare every element of the list with every other elements.
If any two values match (at different positions), we have found a duplicate.

Algorithm (Pseudocode)
FOR i FROM 0 TO length-1
   FOR j FROM i+1 TO length-1
      IF list[i] == list[j]
         RETURN True
RETURN False
Python Implementation
def has_duplicates_bruteforce(data):
   for i in range(len(data)):
      for j in range(i + 1, len(data)):
         if data[i] == data[j]:
            return True
   return False
Big O Notation?

If the list has n items, the outer loop runs n times.
For each of those, the inner loop runs roughly n times.
Total comparisons are approximately:
n × n = n²

  • n = 100 → 10,000 comparisons
  • n = 1,000 → 1,000,000 comparisons
  • n = 10,000 → 100,000,000 comparisons

That growth is quadratic.
We describe this as O(n²) — Polynomial time complexity.

Method 2: Using a Set (Hash Table)

A set in Python:

  • Stores only unique values
  • Allows very fast lookups using a hashing algorithm (average O(1) – Constant Big O Notation to access data)

With this method we access each value of the list one by one and store them in a hash table to we keep track of values we have already seen.
If we ever see a value that is already in the set we have found a duplicate.

Algorithm (Pseudocode)
CREATE empty set called values

FOR each item in list
   IF item is in values
      RETURN True
   ADD item to values

RETURN False

Python Implementation

def has_duplicates_set(data):
   values = set()
   for item in data:
      if item in values:
         return True
      values.add(item)
   return False
Big O Notation?

With this approach, we loop through the list once (n iterations): O(n).
Set lookups and insertions are (on average) constant time: O(1).

  • n = 100 → 100 checks
  • n = 1,000 → 1,000 checks
  • n = 10,000 → 10,000 checks

We describe this as O(n) — linear time complexity.

Comparing Both Methods

n Brute Force (O(n²)) Set Method (O(n))
100 10,000 checks 100 checks
1,000 1,000,000 checks 1,000 checks
10,000 100,000,000 checks 10,000 checks

The difference becomes enormous very quickly.

We can clearly see that as n increases, the second method based on a linear time complexity – O(n), will perform much better than the first approach based on a polynomial time complexity – O(n²)


Python Code

We have implemented both functions in the Python IDE below. Using the time library we are also measuring how long the computer takes to cehck for duplaicates in our randomly generated lists of 5,000 values (n=5,000) using each approach.

Try increasing the size of the list to:

  • 10,000 values
  • 20,000 values
  • 50,000 values

What happens? You should notice the brute-force version slows dramatically.

Key Big O Takeaway

  • Nested loops over the same data usually lead to a O(n²) time complexity
  • Single loop with constant-time operations usually lead to a O(n) time complexity
  • Smarter data structures such as Sets (Hash tables) can dramatically reduce the time complexity of an algorithm
Tagged with:

The Story of Gauss and 1 + 2 + 3 + … + 100

When learning about algorithms, one of the most important ideas in computer science is the Big O Notation. It helps us measure how efficient an algorithm is — especially as the size of the problem gets bigger.

To introduce this concept, let’s travel back to the classroom of a young mathematical genius: Carl Friedrich Gauss (1777 – 1855).
Legend has it that when Gauss was a child, his teacher asked the class to add all the integers from 1 to 100:

1 + 2 + 3 + 4 + ⋯ + 100

The teacher likely expected the students to take a long time adding each number one by one.

But Gauss noticed a clever pattern.

Gauss’ Clever Pairing Method

Carl Friedrich Gauss wrote down the sum adding all the numbers from 1 to 100 in ascending order (from 1 to 100):

1 + 2 + 3 + 4 + ... + 97 + 98 + 99 + 100

Underneath he wrote the same sum, using the same 100 numbers but this time, writing them in descending order (from 100 to 1):

100 + 99 + 98 + 97 + ... + 4 + 3 + 2 + 1

He then paired all these numbers up and realised that each pair added up to 101:

So the total is of all these pairs is :

Sum of all pairs =  100 × 101 = 10,100

But we now have twice as many numbers as needed to caluclate the sum of all the numbers from 1 to 100. So we need to divide this result by 2:

Sum of all numbers from 1 to 100 = 10,100 / 2 = 5,050 

And just like that, Gauss found the answer instantly. From Gauss’ reasoning, we can generalise his approach using the following formula:

We can apply this formula with n=100 or any other value (e.g. n=1,000 or n=1,000,000)

Using an Algorithms

Now let’s compare two approaches to calculate our sum:

  1. Iterative addition (adding numbers one by one)
  2. Gauss’ formula method

Method 1: Iterative Approach

Algorithm (Pseudocode)
total = 0
FOR i FROM 1 TO 100
    total = total + i
END FOR
PRINT total
Python Implementation
def iterative_sum(n):
    total = 0
    for i in range(1, n+1):
        total += i
    return total

print(iterative_sum(100))

This method performs 100 additions when n = 100.

Method 2: Gauss’ Formula

Algorithm (Pseudocode)
total = n × (n + 1) / 2
PRINT total
Python Implementation
def gauss_sum(n):
    return n * (n + 1) / 2

print(gauss_sum(100))

No matter how large n is, this algorithm performs:

  • 1 addition
  • 1 multiplication
  • 1 division

Python Code

We have implemented both functions in the Python IDE below. Using the time library we are also measuring how long the computer takes to calculate the sum using each approach.

Based on our analysis, we believe that the Gauss formula should be more efficient than an iterative approach especially with a very large number for n (e.g. n=1,000,000).

Comparing Efficiency Using Big O Notation

The Big O Notation is used to describe how the running time of an algorithm grows as the input size (n) increases.

With an iterative approach, the loop used to calculate our sum runs n times.
If:

  • n = 100 → 100 operations
  • n = 1,000 → 1,000 operations
  • n = 1,000,000 → 1,000,000 operations

The completion time of this algorithm is pro-rata to the value of n. This is called O(n) — linear time complexity.


Using the Gauss formula, the formula only needs to be executed once, regardless of n. The algorithm always performs the same number of operations — regardless of n.

  • n = 100 → same steps (~3 operations)
  • n = 1,000 → same steps (~3 operations)
  • n = 1,000,000 → same steps (~3 operations)

This is called O(1) — constant time complexity.

What Happens as n Gets Bigger?

n Iterative Operations Gauss Operations
100 100 ~3
1,000 1,000 ~3
1,000,000 1,000,000 ~3
1,000,000,000 1,000,000,000 ~3

As n grows, the difference becomes enormous.
This is why algorithm efficiency matters.

When evaluating the efficiency of an algorithm, the Big O notation helps us answer the following questions:

  • Will this program scale?
  • What happens when the dataset gets huge?
  • Is there a smarter way to solve this problem?

Gauss did not just calculate a sum. He found a more efficient algorithm.
And that is exactly what computer scientists do every day: they use algorithmic thinking to try to find efficient way of solving a problem.

Tagged with: